#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pd_linux.h"
#include "xconfig.h"
#include "xusb_common.h"
#include "xusbdevice.h"
#include "xscsiusb.h"
#include "xscsilibusb.h"
#include "scsi.h"
#ifdef _WIN32
    #include "winScsi.h"
#endif

XUDC_API_BEGIN


#define SDK_VER_MAJOR   1
#define SDK_VER_MINOR   0
#define SDK_VER_BUILD   0

XUDC_DLLEXPORT void APICALL XSCSIUSB_API_PREFIX(version)(int *major, int *minor, int *build)
{
    if(NULL == major || NULL == minor || NULL == build)
    {
        return;
    }
    *major = SDK_VER_MAJOR;
    *minor = SDK_VER_MINOR;
    *build = SDK_VER_BUILD;
}

XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(enumdevice)(int vid, int pid, TXUSBDevice deviceList[], int maxCout)
{
#ifdef _WIN32
    return WinSCSI_EnumDevice(vid, pid, deviceList, maxCout);
#else
    return x_scsi_libusb_enumdevice(vid, pid, deviceList, maxCout);
#endif
}

XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(searchdevice)(unsigned short vid, unsigned short pid, char *szSerialNumber, PXUSBDevice deviceInfo)
{
#ifdef _WIN32
    return WinSCSI_SearchDevice(vid, pid, szSerialNumber, deviceInfo);
#else
    return x_scsi_libusb_searchdevice(vid, pid, szSerialNumber, deviceInfo);
#endif
}

XUDC_DLLEXPORT void *APICALL XSCSIUSB_API_PREFIX(opendevice)(PXUSBDevice usbDevice)
{
#ifdef _WIN32
    return Scsi_Open(usbDevice);
#else
    return x_scsi_libusb_opendevice(usbDevice);
#endif
}

XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(closedevice)(void *handle)
{
#ifdef _WIN32
    return Scsi_Close(handle);
#else
    return x_scsi_libusb_closedevice(handle);
#endif
}

#ifdef __ANDROID__
XUDC_DLLEXPORT void *APICALL XSCSIUSB_API_PREFIX(opendevice_fd)(int vid, int pid, int busNum, int dev_address, int fd)
{
    return x_scsi_libusb_opendevice_fd(vid, pid, busNum, dev_address, fd);
}

XUDC_DLLEXPORT void *APICALL XSCSIUSB_API_PREFIX(opendevice_usbhost)(JavaVM *jvm, JNIEnv *env, jobject obj)
{
    return x_scsi_libusb_opendevice_usbhost(jvm, env, obj);
}

XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(closedevice_usbhost)(JavaVM *jvm, JNIEnv *env, void *handle)
{
    return x_scsi_libusb_closedevice_usbhost(jvm, env, handle);
}

#endif

#ifndef _WIN32
XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(controltransfer)(void *handle, unsigned char bmRequestType, unsigned char bRequest, unsigned short wValue, unsigned short wIndex,
                                                                unsigned char *data, unsigned short wLength, unsigned int timeout)
{
    return x_scsi_libusb_controltransfer(handle, bmRequestType, bRequest, wValue, wIndex,
                                         data, wLength, timeout);
}

XUDC_DLLEXPORT void APICALL XSCSIUSB_API_PREFIX(resetdevice)(void *handle)
{
    return x_scsi_libusb_resetdevice(handle);
}


#endif

XUDC_DLLEXPORT BOOL APICALL XSCSIUSB_API_PREFIX(write)(void *hDevice, unsigned char *DataBuffer, int DataTransferLength, int TimeOutValue)
{
    return Scsi_Write(hDevice, DataBuffer, DataTransferLength, TimeOutValue);
}

XUDC_DLLEXPORT BOOL APICALL XSCSIUSB_API_PREFIX(read)(void *hDevice, unsigned char *DataBuffer, int DataTransferLength, int TimeOutValue)
{
    return Scsi_Write(hDevice, DataBuffer, DataTransferLength, TimeOutValue);
}

XUDC_DLLEXPORT int APICALL XSCSIUSB_API_PREFIX(inquiry)(void *hDevice, unsigned char *buffer, int cbBuffer)
{
    return Scsi_Inquiry(hDevice, buffer, cbBuffer);
}

XUDC_DLLEXPORT BOOL APICALL XSCSIUSB_API_PREFIX(transmit)(void *hDevice, unsigned char *cdb, unsigned int cdbSize, unsigned char DataIn, unsigned char *DataBuffer, int DataTransferLength, int timeOut)
{
    return Scsi_Transmit(hDevice, cdb, cdbSize, DataIn, DataBuffer, DataTransferLength, timeOut);
}


XUDC_API_END